//
// Created by jyc on 2021/10/2.
//

#ifndef BFALCOR_RENDERGRAPH_H
#define BFALCOR_RENDERGRAPH_H

#include <algorithm>
#include "RenderPass.h"
#include "DirectedGraph.h"
#include "ResourceManager.h"
namespace Bonnie{
    
    class RenderGraph {
    public:
        void addPass(const IRenderPass::SharedPtr& pass,const std::string& name);

        void compile();
        void RenderUI();
        using SharedPtr = std::shared_ptr< RenderGraph>;
        static SharedPtr create() {
            auto ins = std::make_shared<RenderGraph>();
            ins->mpResourceManager = ResourceManager::create();
            return ins;
        }
    private:
        /**
         * add a edge by field name
         * @param src "pass`s name"."output field"
         * @param dst "pass`s name"."input field"
         */
        void addEdge(const std::string & src,const std::string& dst);

        /**
         * parse the string
         * @param fullname
         * @return the first is pass`name and the second is field
         */
        std::pair<std::string,std::string> parseFieldName(const std::string& fullname);
        struct EdgeData{
            std::string srcFullName;
            std::string dstFullName;
        };

        struct NodeData{
            std::string name;
            IRenderPass::SharedPtr pass;
        };

        DirectedGraph mDGraph;
        ResourceManager::SharedPtr mpResourceManager;
        std::unordered_map<std::string,uint32_t > mPassName2NodeIdx;
        std::unordered_map<uint32_t ,EdgeData> mEdgeIdx2EdgeData;
        std::unordered_map<uint32_t ,NodeData> mNodeIdx2NodeData;

        std::unordered_map<int,std::string> mAttrId2fullname;
        std::unordered_map<std::string,int> mFullname2attrId;

        ////
        // compiler data
        ////
        struct CompilerNodeData {
            uint32_t nodeId;
            NodeData* nodeInfo;
        };
        std::vector<CompilerNodeData> mExcutionList;
    };

}

#endif //BFALCOR_RENDERGRAPH_H
